<template>
  <div class="m7-select">
    <el-popover
      ref="popover4"
      placement="bottom"
      :width="inputWidth || 190"
      :disabled="disabled"
      @show="popoverShow"
      v-model="visible"
      v-show="visible"
      transition=""
      @after-leave="popoverHide"
      :popper-class="multiple ? 'el-select-dropdown is-multiple padding-no' : (type == 'business'? 'el-select-dropdown padding-no selectDropStyle': 'el-select-dropdown padding-no')"
      trigger="click">
      <ul class="el-select-dropdown__list">
          <li class="el-select-dropdown__item"  v-if="this.type === 'business' && optionsArrShow.length !== 0" @click="changeDefault('')">{{this.$t('public.pleasePick')}}</li>
          <li class="el-select-dropdown__item" v-for="(item, index) in optionsArrShow" :key="index" @click="nodeClick(item)" :class="{selected: item.select, 'is-disabled': item.disabled}" v-show="item.visible">{{item.label}}</li>
          <li v-if="optionsArrShow.length === 0" class="el-select-dropdown__empty">无匹配数据</li>
      </ul>
    </el-popover>
    <div class="el-select el-select--mini">
      <div v-popover:popover4 @click="inputClick">
        <div class="el-select__tags tag-input" v-if="multiple" :style="{ 'max-width': inputWidth - 32 + 'px' }">
            <el-tag
              class="tag"
              v-if="value.length"
              size="mini"
              type="info"
              @close="close"
              closable>
              <span class="el-select__tags-text tag-max">{{tagName}}</span>
            </el-tag>
            <el-tag type="info" size="mini" v-if="value.length > 1">+{{value.length - 1}}</el-tag>
            <input type="text"
                 v-if="filterable"
                 autocomplete="off"
                 class="el-select__input is-mini"
                 @focus="focus"
                 @blur="blur"
                 :style="{ 'width': mulitInputwidth + 'px' }"
                 ref="input" v-model="query">
        </div>
        <el-input
          v-if="multiple"
          ref="reference"
          v-model="noquery"
          type="text"
          :placeholder="cachedPlaceHolder"
          :auto-complete="'off'"
          :size="'small'"
          :validate-event="false"
          :disabled="disabled"
          :readonly="true"
          :class="{ 'is-focus': visible, 'is-label': palaceHolderStyle}">
          <template slot="prefix" v-if="$slots.prefix">
            <slot name="prefix"></slot>
          </template>
          <i slot="suffix"
          :class="['el-select__caret', 'el-input__icon', 'el-icon-arrow-up', iconClass]"
          ></i>
        </el-input>
        <el-input
          v-if="!multiple"
          ref="reference"
          v-model="query"
          type="text"
          :placeholder="cachedPlaceHolder"
          :auto-complete="'off'"
          :size="'small'"
          :validate-event="false"
          :disabled="disabled"
          :readonly="readonly"
          :class="{ 'is-focus': visible, 'is-label': palaceHolderStyle}">
          <template slot="prefix" v-if="$slots.prefix">
            <slot name="prefix"></slot>
          </template>
          <i slot="suffix"
          :class="['el-select__caret', 'el-input__icon', 'el-icon-arrow-up', iconClass]"
          ></i>
        </el-input>
      </div>
    </div>
  </div>
</template>

<script>
  import {isEqual} from 'lodash'
  import Emitter from '../tree/polyfill/emitter'
  import { addResizeListener, removeResizeListener } from './resize-event'
  export default {
    name: 'm7Select',
    mixins: [Emitter],
    props: {
      name: String,
      id: String,
      value: {
        required: true
      },
      autoComplete: {
        type: String,
        default: 'off'
      },
      automaticDropdown: Boolean,
      size: String,
      disabled: Boolean,
      clearable: Boolean,
      filterable: Boolean,
      allowCreate: Boolean,
      loading: Boolean,
      popperClass: String,
      remote: Boolean,
      loadingText: String,
      noMatchText: String,
      noDataText: String,
      remoteMethod: Function,
      filterMethod: Function,
      multiple: Boolean,
      multipleLimit: {
        type: Number,
        default: 0
      },
      placeholder: {
        type: String,
        default () {
          return this.$t('public.pleasePick')
        }
      },
      defaultFirstOption: Boolean,
      reserveKeyword: Boolean,
      valueKey: {
        type: String,
        default: 'value'
      },
      collapseTags: Boolean,
      popperAppendToBody: {
        type: Boolean,
        default: true
      },
      defaultProps: {
        type: Object,
        default: function () {
          return {value: 'value', label: 'label'}
        }
      },
      options: {
        type: Array,
        default: function () {
          let arr = []
          for (let i = 0; i < 5000; i++) {
            arr.push({label: i + 'x', value: i + 'x'})
          }
          return arr
        }
      },
      type:String
    },
    data () {
      return {
        tagName: '',
        visible: false,
        query: '',
        noquery: '', // 多选时占位
        maxIndex: 100,
        inputWidth: 0,
        timer: ''
      }
    },
    components: {
    },
    computed: {
      cachedPlaceHolder () {
        if (this.multiple) {
          return (this.value.length || this.query) ? '' : this.placeholder
        } else {
          return this.tagName || this.placeholder
        }
      },
      palaceHolderStyle () {
        if (this.multiple) {
          return this.value.length > 0
        } else {
          return this.tagName
        }
      },
      mulitInputwidth () {
        if (this.multiple) {
          if (!this.value.length) {
            return this.inputWidth - 40
          } else if (this.value.length === 1) {
            return this.inputWidth - 125
          }
          return this.inputWidth - 155
        }
      },
      tagId () {
        if (this.multiple) {
          return this.value[0]
        } else {
          return this.value
        }
      },
      optionsArr () {
        let label = this.defaultProps.label
        let value = this.defaultProps.value
        let options = this.options || []
        let self = this
        if(this.type === 'business'){
          return options.map((item) => {
            let select = false
            if (self.multiple) {
              select = self.value.some(one => one === item[value])
            } else {
              select = self.value === item[value]
            }
            let visible = true
            if (self.query && item.name && item.name.indexOf(self.query) === -1) {
              visible = false
            }
            return {label: item.name, value: item.key, visible, select, disabled: item.disabled}
          })
        }else{
          return options.map((item) => {
            let select = false
            if (self.multiple) {
              select = self.value.some(one => one === item[value])
            } else {
              select = self.value === item[value]
            }
            let visible = true
            if (self.query && item[label] && item[label].indexOf(self.query) === -1) {
              visible = false
            }
            return {label: item[label], value: item[value], visible, select, disabled: item.disabled}
          })
        }
      },
      optionsArrShow () {
        let optionsArr = this.optionsArr
        return optionsArr.filter((item, index) => {
          if (index < this.maxIndex && item.visible) {
            return true
          }
        })
      },
      readonly () {
        // trade-off for IE input readonly problem: https://github.com/ElemeFE/element/issues/10403
        const isIE = !this.$isServer && !isNaN(Number(document.documentMode))
        return !this.filterable || this.multiple || !isIE && !this.visible
      },
      iconClass () {
        return this.visible ? 'is-reverse ' : ''
      }
    },
    watch: {
      tagId (val) {
        this.getTagName(val)
      },
      visible (val) {
        this.$emit('visible-change', val)
      },
      options(){
        // 当工单使用时，执行下列方法支持回显
        if(this.type === 'business'){
          this.getTagName(this.tagId)
        }
      }
    },
    methods: {
      // 分批加载
      handler () {
        this.maxIndex = 100
        window.clearInterval(this.timer)
        this.timer = window.setInterval(() => {
          this.maxIndex += 200
          if (this.maxIndex > this.options.length) {
            window.clearInterval(this.timer)
          }
        }, 10)
      },
      nodeClick (item) {
        if (item.disabled) {
          return
        }
        if (this.multiple) {
          this.$refs.input && this.$refs.input.focus()
          this.query = ''
          let value = JSON.parse(JSON.stringify(this.value))
          let index = value.indexOf(item.value)
          if (index !== -1) {
            value.splice(index, 1)
          } else {
            value.push(item.value)
          }
          this.$emit('input', value)
          this.emitChange(value)
        } else {
          // 单选
          this.visible = false
          this.query = ''
          this.$emit('input', item.value)
          this.emitChange(item.value)
        }
      },
      changeDefault(val){
        this.$emit('input', val)
        this.visible = false
      },
      getTagName (val) {
        this.tagName = ''
        if (val !== undefined) {
          let self = this
          this.optionsArr.some((item) => {
            if (item.value === val) {
              self.tagName = item.label
            }
          })
        }
      },
      blur () {},
      focus () {},
      close () {
        if (this.value.length) {
          let value = JSON.parse(JSON.stringify(this.value))
          this.$emit('input', value.slice(1))
        }
      },
      emitChange (val) {
        if (!isEqual(this.value, val)) {
          this.$emit('change', val)
          this.dispatch('ElFormItem', 'el.form.change', val)
        }
      },
      inputClick () {
        if (this.disabled) {
          return
        }
        this.$refs.input && this.$refs.input.focus()
      },
      popoverShow () {
        this.$nextTick(() => {
          this.handler()
        })
      },
      popoverHide () {
        this.$refs.input && this.$refs.input.blur()
        this.$nextTick(() => {
          this.query = ''
          this.maxIndex = 100
          window.clearInterval(this.timer)
        })
      },
      resetInputWidth () {
        this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width
      }
    },
    mounted () {
      addResizeListener(this.$el, this.resetInputWidth)
      this.getTagName(this.tagId)
      this.$nextTick(() => {
        if (this.$refs.reference && this.$refs.reference.$el) {
          this.resetInputWidth()
        }
      })
    },
    created () {
      if (this.multiple && !Array.isArray(this.value)) {
        this.$emit('input', [])
      }
      if (!this.multiple && Array.isArray(this.value)) {
        this.$emit('input', '')
      }
      this.$on('fieldReset', () => {
        this.dispatch('ElFormItem', 'el.form.change')
      })
    },
    beforeDestroy () {
      window.clearInterval(this.timer)
      if (this.$el && this.resetInputWidth) removeResizeListener(this.$el, this.resetInputWidth)
    }
  }
</script>
<style lang="stylus">
  .padding-no
    padding 0
  .m7-select
    .is-label
      input::-webkit-input-placeholder
        color #000 !important
  .selectDropStyle
    min-width 190px !important
</style>
<style scoped lang="stylus">
  @import "../../../assets/common.styl"
  .m7-select
    display inline-block
    width 100%
    &:hover
      cursor pointer
  .el-select
    width 100%
    box-sizing border-box
  // 覆盖ele升级得样式
  .el-select .el-select__tags>span
    display: flex;
  .tag
    display: flex;
    align-items: center;
  .tag-input
    width calc(100% - 20px)
    display flex
    flex-direction row
    flex-wrap nowrap
    justify-content left
  .tag-max
    max-width 60px
    display inline-block
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
  .el-select__input
    width 20px
  .el-select-dropdown__list
    max-height 260px
    overflow-y auto
</style>
